from datetime import datetime, timedelta
from typing import Annotated, Optional

from fastapi import APIRouter, Depends, BackgroundTasks, Request, Body, Path
from loguru import logger

from sanren.utils import get_current_active_user, Helper
from application.http import models
from application.http.models import OemModel, CodeModel
from application.http.schemas import ApiSchemas
from application.http import schemas
from application.config import appSettings
from sanren.extensions import DingBot


router = APIRouter(prefix='/brand/users', tags=['Brand'])
module_name = '品牌商模块'


@router.get('', response_model=schemas.BaseApiListOut)
async def get_companies(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    page_params: schemas.PageParams = Depends(),
    keyword: Optional[str] = None,
):
    """
        品牌商用户列表
    """

    objs = OemModel.Company.with_('children').with_('brand_user').where('parent_id', 0)

    if keyword:
        objs = objs.where(lambda query: query.where('brand_id', 'like', f'%{keyword}%').or_where('name', 'like', f'%{keyword}%').or_where('code', 'like', f'%{keyword}%'))

    objs = objs.order_by('id', 'desc').paginate(page_params.pageSize, page_params.page)

    return objs.serialize()


@router.post('', response_model=schemas.BaseApiOut)
async def add_company(
    current_user: Annotated[object, Depends(get_current_active_user)],
    background_tasks: BackgroundTasks,
    request: Request,
    post: ApiSchemas.brand.CompanyCreate,
):
    """
        添加品牌商用户

        企业代码 变更为 品牌商 ID,原有品牌 code 的判断逻辑舍弃 => At 20250218
    """

    last_id = OemModel.Company.order_by('id', 'desc').first()
    if last_id is None or last_id.brand_id is None or last_id.brand_id == '':
        brand_id = appSettings.first_customer_id
    else:
        brand_id = last_id.brand_id + 1

    try:
        obj = OemModel.Company.create(
            code=brand_id,
            brand_id=brand_id,
            name=post.name,
            email=post.email,
            salesman=post.salesman,
            country=post.country,
            industry=post.industry,
            contacts_name=post.contacts_name,
            contacts_tell=post.contacts_tell,
            status=post.status,
            user_id=current_user.id,  # 管理员信息
        )

        # 新版本集成 自动生成
        # 商户创建成功后，商户号后台自动开启，并匹配默认账号密码，直接发送到钉钉(账号规则:lg+品牌ID，密码规则:大小写字母+数字+特殊符号，长度大于8位)
        obj = obj.fresh()
        background_tasks.add_task(register_brand_user, obj=obj)

        return {'message': '操作成功'}
    except Exception as e:
        return schemas.BaseApiOut(code=1, message=f'操作失败: {str(e)}')


async def register_brand_user(obj):
    """
        注册品牌商用户
    """

    # 生成用户名和密码
    username = f'lg{obj.brand_id}'
    password = ''.join(Helper.random_str(length=16, ctype=8))

    try:
        brand_user = OemModel.BrandUser()
        brand_user.type = 1
        brand_user.code = obj.code
        brand_user.brand_id = obj.brand_id
        brand_user.username = username
        brand_user.name = username
        brand_user.email = f'{username}@{obj.brand_id}'
        brand_user.is_active = 1
        brand_user.password_hash = OemModel.BrandUser.get_password_hash(password)
        brand_user.save()

        logger.info(f'注册品牌商用户成功:{username}')
    except Exception as e:
        logger.info(f'注册品牌商用户失败:{str(e)}')
        return

    # 推送到 Ding WebHook 机器人
    bot = DingBot(access_token=appSettings.ding_bot_token)
    msg = '#### 品牌商用户开户成功 \n\n > 商户名称: {name} \n\n > 品牌商ID: {brand_id} \n\n ##### 品牌商账户 \n\n > 用户名: {username} \n\n > 密码: {password}'
    logger.info('发送 dingbot 消息')
    await bot.send_markdown(msg=msg.format(name=obj.name, brand_id=obj.brand_id, username=username, password=password))


@router.get('/code', response_model=schemas.BaseApiListOut)
async def code(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    code: str,
):
    """
        品牌商 是不是存在
    """
    obj = OemModel.Company.where('code', code).first()
    if obj is None:
        return schemas.BaseApiOut(code=1, message='品牌商不存在')

    return {'data': obj.serialize()}


@router.get('/appbrands', response_model=schemas.BaseApiListOut)
async def app_brands(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    page_params: schemas.PageParams = Depends(),
    brand_id: Optional[int] = None,
    keyword: Optional[str] = None,
):
    """
        品牌商 开通应用记录
    """
    objs = OemModel.ExAppBrand.with_('app').with_('brand')

    if brand_id:
        objs = objs.where('brand_id', brand_id)

    if keyword:
        objs = objs.where(lambda query: query.where('brand_id', 'like', f'%{keyword}%').or_where('app_slug', 'like', f'%{keyword}%').or_where('remarks', 'like', f'%{keyword}%'))

    objs = objs.order_by('id', 'desc').paginate(page_params.pageSize, page_params.page)

    for item in objs:
        item.register_date = item.register_date.strftime("%Y-%m-%d") if item.register_date else None
        item.start_date = item.start_date.strftime("%Y-%m-%d") if item.start_date else None
        item.end_date = item.end_date.strftime("%Y-%m-%d") if item.end_date else None

    return objs.serialize()


@router.post('/appbrands', response_model=schemas.BaseApiListOut)
async def app_brand_create(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    post: dict = Body(),
):
    """
        品牌商 开通应用记录
    """
    if not post['brand_id'] or not post['app_slug'] or not post['bill_years'] or not post['start_date']:
        return {'code': 1, 'status': 1, 'message': '缺少必要参数'}

    if not OemModel.ExApp.where('slug', post['app_slug']).first():
        return {'code': 1, 'status': 1, 'message': '找不到此应用'}

    if not OemModel.Company.where('brand_id', post['brand_id']).first():
        return {'code': 1, 'status': 1, 'message': '找不到此商户'}

    if OemModel.ExAppBrand.where('app_slug', post['app_slug']).where('brand_id', post['brand_id']).first():
        return {'code': 1, 'status': 1, 'message': '此商户已经存在此应用的开通记录，请选择更新操作即可'}

    try:
        end_date = datetime.strptime(post['start_date'], '%Y-%m-%d') + timedelta(days=365 * int(post['bill_years']))

        insertData = {
            'brand_id': post['brand_id'],
            'app_slug': post['app_slug'],
            'register_date': datetime.now().strftime('%Y-%m-%d'),
            'start_date': post['start_date'],
            'end_date': end_date,
            'bill_years': post['bill_years'],
            'remarks': post['remarks'],
        }

        OemModel.ExAppBrand.create(insertData)
    except Exception as e:
        return {'code': 1, 'status': 1, 'message': f'出错了: {str(e)}'}

    return {'status': 0, 'code': 0, 'message': 'success'}


@router.put('/appbrands/{id}', response_model=schemas.BaseApiListOut)
async def app_brand_update(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    post: dict = Body(),
    id: int = Path(...),
):
    """
        品牌商 开通应用记录更新
    """
    obj = OemModel.ExAppBrand.where('id', id).first()
    if obj is None:
        return {'code': 1, 'status': 1, 'message': '找不到此记录'}

    # 相关信息
    try:
        end_date = datetime.strptime(post['start_date'], '%Y-%m-%d') + timedelta(days=365 * int(post['bill_years']))

        obj.bill_years = post['bill_years']
        obj.start_date = post['start_date']
        obj.end_date = end_date.strftime('%Y-%m-%d')
        obj.remarks = post['remarks']
        obj.save()
    except Exception as e:
        return {'code': 1, 'status': 1, 'message': f'出错了: {str(e)}'}

    return {'status': 0, 'code': 0, 'message': 'success'}


@router.delete('/appbrands/{id}', response_model=schemas.BaseApiListOut)
async def app_brand_delete(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    id: int = Path(...),
):
    """
        品牌商 开通应用记录删除
    """
    obj = OemModel.ExAppBrand.where('id', id).first()
    if obj is None:
        return {'code': 1, 'status': 1, 'message': '找不到此记录'}

    # 删除相关信息
    try:
        obj.delete()
    except Exception as e:
        return {'code': 1, 'status': 1, 'message': f'出错了: {str(e)}'}

    return {'status': 0, 'code': 0, 'message': 'success'}


@router.post('/apitoken/{id}', response_model=schemas.BaseApiOut)
async def api_token(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    id: int,
):
    """
        品牌商用户开通 API Token
    """

    obj = OemModel.Company.find(id)
    if obj is None:
        return schemas.BaseApiOut(code=1, message='品牌商用户不存在')
    if obj.api_token is not None and obj.api_token != '':
        return schemas.BaseApiOut(code=1, message='已经拥有 api token,无需再次获取')

    try:
        api_token_arr = Helper.random_str(length=32, ctype=6)
        api_token = ''.join(api_token_arr)

        obj.api_token = api_token
        obj.save()
    except Exception as e:
        return schemas.BaseApiOut(code=1, message=f'操作失败: {str(e)}')

    return {'data': api_token}


@router.get('/{id}', response_model=schemas.BaseApiOut)
async def get_company(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    id: int | str,
):
    """
        编辑品牌商用户
    """

    obj = OemModel.Company.find(id)
    if obj is None:
        obj = OemModel.Company.where('brand_id', id).or_where('code', id).first()
        if obj is None:
            return schemas.BaseApiOut(code=1, message='品牌商用户不存在')

    return {'data': obj.serialize()}


@router.put('/{id}', response_model=schemas.BaseApiOut)
async def edit_company(
    current_user: Annotated[object, Depends(get_current_active_user)],
    request: Request,
    post: ApiSchemas.brand.CompanyCreate,
    id: int,
):
    """
        编辑品牌商用户
    """

    obj = OemModel.Company.find(id)
    if obj is None:
        return schemas.BaseApiOut(code=1, message='品牌商用户不存在')

    try:
        # 更新企业
        obj.salesman = post.salesman or None
        obj.name = post.name
        obj.email = post.email
        obj.country = post.country
        obj.industry = post.industry
        obj.contacts_name = post.contacts_name
        obj.contacts_tell = post.contacts_tell
        obj.status = post.status
        obj.save()

        print('操作成功')
    except Exception as e:
        return schemas.BaseApiOut(code=1, message=f'操作失败: {str(e)}')

    return {}
